#pragma once

#include "CreateFileParams.h"
#include "../header/Inode.h"
#include "../header/FCB.h"

// 从当前目录中查找文件或目录的FCB地址，没找到返回-1
static short Path_findFileOrDir(FCB *fcbList, Inode *inodeList, int workDirPtr, char *fileName) {
    FCB *dirFCB = fcbList + workDirPtr;
    Inode *dirInode = inodeList + dirFCB->inodeNumber;
    RETURN_IF_TRUE(dirInode->leftmostChild == NOTHING, NOTHING)
    short currentFCBPtr = dirInode->leftmostChild;
    FCB *currentFCB = fcbList + currentFCBPtr;
    Inode *currentInode = inodeList + currentFCB->inodeNumber;
    while (True) {
        if (String_equal(currentFCB->name, fileName)) {
            return currentFCBPtr;
        }
        if (currentInode->rightSibling == NOTHING) {
            return NOTHING;
        }
        currentFCBPtr = currentInode->rightSibling;
        currentFCB = fcbList + currentFCBPtr;
        currentInode = inodeList + currentFCB->inodeNumber;
    }
}

static Boolean Path_isParent(FCB *fcbList, Inode *inodeList, int workDirPtr, int currentDir) {
    FCB *tempFCB = fcbList + currentDir;
    Inode *tempInode = inodeList + tempFCB->inodeNumber;
    while (True) {
        if (currentDir == NOTHING) {
            return False;
        }
        if (currentDir == workDirPtr) {
            return True;
        }
        currentDir = tempInode->parent;
        tempFCB = fcbList + currentDir;
        tempInode = inodeList + tempFCB->inodeNumber;
    }
}

static short Path_getOrCreateWorkDir(FCB *fcbList, Inode *inodeList, PathInfo *pathInfo,
                           short currentDir, Boolean createIfNotExist) {
    if (pathInfo->fromRoot) {
        currentDir = 0;
    }
    for (int i = 0; i < pathInfo->pathSize; ++i) {
        char *pathEle = pathInfo->path[i];
        RETURN_IF_TRUE(strlen(pathEle) > MAX_FILE_NAME_LENGTH, NOTHING)
        if (String_equal(pathEle, "."))
            continue;
        if (String_equal(pathEle, "..")) {
            // 返回上一级
            short parentPtr = inodeList[fcbList[currentDir].inodeNumber].parent;
            if (parentPtr != NOTHING) {
                currentDir = parentPtr;
            } else {
                return NOTHING;
            }
        } else {
            // 下一级
            short tempFCBPtr = Path_findFileOrDir(fcbList, inodeList, currentDir, pathEle);
            if (tempFCBPtr == NOTHING) { // 目录不存在
                if (createIfNotExist) {
                    short tempInodePtr = InodeList_createInode(inodeList, 0, currentDir, True);
                    tempFCBPtr = FCBList_createFCB(fcbList, pathEle, tempInodePtr);
                    Inode *tempInode = inodeList + fcbList[currentDir].inodeNumber;
                    Inode_addChild(fcbList, inodeList, tempInode, tempFCBPtr);
                    currentDir = tempFCBPtr;
                } else {
                    return NOTHING;
                }
            } else if (inodeList[fcbList[tempFCBPtr].inodeNumber].indirectBlock < 0) {
                currentDir = tempFCBPtr;
            } else { // 不是目录，是重名文件
                return NOTHING;
            }
        }
    }
    return currentDir;
}
